package rpc_netty.Handler;

import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rpc_netty.server.ServiceProvider.DefaultServiceProvider;
import rpc_1.Service.RpcException;
import rpc_1.interfaces.ServiceProvider;
import rpc_1.object.ResponseCode;
import rpc_1.object.RpcRequest;
import rpc_1.object.RpcResponse;


public class NettyServerHandler extends SimpleChannelInboundHandler<RpcRequest> {
    private static final Logger logger= LoggerFactory.getLogger(NettyServerHandler.class);
    private static RequestHandler requestHandler;
    private static ServiceProvider serviceProvider;

    static {
        requestHandler=new RequestHandler();
        serviceProvider=new DefaultServiceProvider();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest msg) throws Exception {
        try {
            logger.info("server receive the message,{}",msg);
            String interfaceName = msg.getInterfaceName();
            Object service = serviceProvider.getService(interfaceName);
            Object result = requestHandler.handle(msg, service);
            ResponseCode responseCode = new ResponseCode();
            if (result!=null){
                responseCode.setSUCCESS_CODE(1);
                responseCode.setMessage("success!");
            }else {
                responseCode.setSUCCESS_CODE(0);
                responseCode.setMessage("rpc fail!");
            }
            ChannelFuture future = ctx.writeAndFlush(RpcResponse.success(result, responseCode));
            future.addListener(ChannelFutureListener.CLOSE);
        } catch (RpcException e) {
            e.printStackTrace();
        }finally {
            ReferenceCountUtil.release(msg);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("error when invoking");
        cause.printStackTrace();
        ctx.close();
    }
}
